bitkeeper revision 1.1026.3.1 (40e1966bdTS8WBGJY9WhLRE3t6GBdQ)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Tue, 29 Jun 2004 16:18:51 +0000 (16:18 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Tue, 29 Jun 2004 16:18:51 +0000 (16:18 +0000)
More cleanups for x86-64.

13 files changed:
.rootkeys
xen/arch/x86/boot/boot.S
xen/arch/x86/mm.c
xen/common/kernel.c
xen/common/memory.c
xen/common/shadow.c
xen/include/asm-x86/config.h
xen/include/asm-x86/page.h
xen/include/asm-x86/string.h
xen/include/asm-x86/types.h
xen/include/asm-x86/x86_32/string.h [new file with mode: 0644]
xen/include/asm-x86/x86_64/string.h [new file with mode: 0644]
xen/include/xen/mm.h

index 7bfcd6a45e85bff53f1db67b94eb995dbc1577cb..9ed95dbc18cc03249ee8fb061cfec4a69191c915 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
 3ddb79c3Hgbb2g8CyWLMCK-6_ZVQSQ xen/include/asm-x86/smp.h
 3ddb79c3jn8ALV_S9W5aeTYUQRKBpg xen/include/asm-x86/smpboot.h
 3ddb79c3NiyQE2vQnyGiaBnNjBO1rA xen/include/asm-x86/spinlock.h
-3e7f358aG11EvMI9VJ4_9hD4LUO7rQ xen/include/asm-x86/string.h
+40e1966akOHWvvunCED7x3HPv35QvQ xen/include/asm-x86/string.h
 3ddb79c3ezddh34MdelJpa5tNR00Dw xen/include/asm-x86/system.h
 3ddb79c4HugMq7IYGxcQKFBpKwKhzA xen/include/asm-x86/types.h
 40cf1596saFaHD5DC5zvrSn7CDCWGQ xen/include/asm-x86/uaccess.h
 3ddb79c2ADvRmdexd9y3AYK9_NTx-Q xen/include/asm-x86/x86_32/current.h
 3ddb79c3mbqEM7QQr3zVq7NiBNhouA xen/include/asm-x86/x86_32/ptrace.h
+3e7f358aG11EvMI9VJ4_9hD4LUO7rQ xen/include/asm-x86/x86_32/string.h
 3ddb79c3M2n1ROZH6xk3HbyN4CPDqg xen/include/asm-x86/x86_32/uaccess.h
 404f1b9ceJeGVaPNIENm2FkK0AgEOQ xen/include/asm-x86/x86_64/current.h
 404f1b9fl6AQ_a-T1TDK3fuwTPXmHw xen/include/asm-x86/x86_64/desc.h
 404f1badfXZJZ2sU8sh9PS2EZvd19Q xen/include/asm-x86/x86_64/ldt.h
 404f1bb1LSCqrMDSfRAti5NdMQPJBQ xen/include/asm-x86/x86_64/page.h
 404f1bb86rAXB3aLS1vYdcqpJiEcyg xen/include/asm-x86/x86_64/ptrace.h
+40e1966azOJZfNI6Ilthe6Q-T3Hewg xen/include/asm-x86/x86_64/string.h
 404f1bc4tWkB9Qr8RkKtZGW5eMQzhw xen/include/asm-x86/x86_64/uaccess.h
 400304fcmRQmDdFYEzDh0wcBba9alg xen/include/hypervisor-ifs/COPYING
 404f1bc68SXxmv0zQpXBWGrCzSyp8w xen/include/hypervisor-ifs/arch-x86_32.h
index ebb74c6562fdb8f62fedda33be382a86fb43c543..55a4cc4cc2640cb629dee610357f9de18730ab9e 100644 (file)
@@ -101,7 +101,7 @@ continue_boot_cpu:
         mov     0x4(%eax),%eax               /* %eax = mod[mod_count-1]->end */
         mov     %eax,%ecx
         sub     %ebx,%ecx                    /* %ecx = byte len of all mods */
-        mov     $(MAX_DIRECTMAP_ADDRESS), %edi
+        mov     $(DIRECTMAP_PHYS_END), %edi
         add     %ecx, %edi                   /* %edi = src + length */        
         shr     $2,%ecx                      /* %ecx = length/4 */
 1:      sub     $4,%eax                      /* %eax = src, %edi = dst */
@@ -117,7 +117,7 @@ skip_dom0_copy:
 1:      mov     %eax,__PAGE_OFFSET>>20(%edi) /* high mapping */
         stosl                                /* low mapping */
         add     $(1<<L2_PAGETABLE_SHIFT),%eax
-        cmp     $MAX_DIRECTMAP_ADDRESS+0x1e3,%eax
+        cmp     $DIRECTMAP_PHYS_END+0x1e3,%eax
         jne     1b
 
         call    start_paging        
index d61df0d9a1671acfa3f437074081caa4208c6ab2..59e304e4a77574128f96dc8129d6aab1378a7a28 100644 (file)
@@ -347,7 +347,7 @@ void *memguard_init(void *heap_start)
                           PAGE_MASK);
 
     /* Memory guarding is incompatible with super pages. */
-    for ( i = 0; i < (MAX_XENHEAP_ADDRESS >> L2_PAGETABLE_SHIFT); i++ )
+    for ( i = 0; i < (xenheap_phys_end >> L2_PAGETABLE_SHIFT); i++ )
     {
         l1 = (l1_pgentry_t *)heap_start;
         heap_start = (void *)((unsigned long)heap_start + PAGE_SIZE);
index 001227257e17d784339b2c916be03ee7cd89e5ca..92602e0bf5830995265e93ba5d7fa4f8698f4927 100644 (file)
@@ -27,6 +27,8 @@
 #include <asm/domain_page.h>
 #include <hypervisor-ifs/dom0_ops.h>
 
+unsigned long xenheap_phys_end;
+
 kmem_cache_t *domain_struct_cachep;
 
 struct e820entry {
@@ -69,6 +71,11 @@ char opt_physdev_dom0_hide[200] = "";
 /*                                    level- or edge-triggered.         */
 /* Example: 'leveltrigger=4,5,6,20 edgetrigger=21'. */
 char opt_leveltrigger[30] = "", opt_edgetrigger[30] = "";
+/*
+ * opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the
+ * pfn_info table and allocation bitmap.
+ */
+unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
 
 static struct {
     unsigned char *name;
@@ -91,6 +98,7 @@ static struct {
     { "physdev_dom0_hide", OPT_STR,  &opt_physdev_dom0_hide },
     { "leveltrigger",      OPT_STR,  &opt_leveltrigger },
     { "edgetrigger",       OPT_STR,  &opt_edgetrigger },
+    { "xenheap_megabytes", OPT_UINT, &opt_xenheap_megabytes },
     { NULL,               0,        NULL     }
 };
 
@@ -180,52 +188,78 @@ void cmain(unsigned long magic, multiboot_info_t *mbi)
         for ( ; ; ) ;
     }
 
+    if ( opt_xenheap_megabytes < 4 )
+    {
+        printk("Xen heap size is too small to safely continue!\n");
+        for ( ; ; ) ;
+    }
+
+    set_current(&idle0_task);
+
+    xenheap_phys_end = opt_xenheap_megabytes << 20;
+
     max_mem = max_page = (mbi->mem_upper+1024) >> (PAGE_SHIFT - 10);
 
-    /* The array of pfn_info structures must fit into the reserved area. */
-    if ( (sizeof(struct pfn_info) * max_page) >
-         (FRAMETABLE_VIRT_END - FRAMETABLE_VIRT_START) )
+#if defined(__i386__)
+
+    if ( opt_xenheap_megabytes > XENHEAP_DEFAULT_MB )
     {
-        unsigned long new_max =
-            (FRAMETABLE_VIRT_END - FRAMETABLE_VIRT_START) /
-            sizeof(struct pfn_info);
-        printk("Truncating available memory to %lu/%luMB\n",
-               new_max >> (20 - PAGE_SHIFT), max_page >> (20 - PAGE_SHIFT));
-        max_page = new_max;
+        printk("Xen heap size is limited to %dMB - you specified %dMB.\n",
+               XENHEAP_DEFAULT_MB, opt_xenheap_megabytes);
+        for ( ; ; ) ;
     }
 
-    set_current(&idle0_task);
+    ASSERT((sizeof(struct pfn_info) << 20) >
+           (FRAMETABLE_VIRT_END - FRAMETABLE_VIRT_START));
 
-    init_frametable(max_page);
-    printk("Initialised %luMB memory (%lu pages) on a %luMB machine\n",
-           max_page >> (20-PAGE_SHIFT), max_page,
-          max_mem  >> (20-PAGE_SHIFT));
+    init_frametable((void *)FRAMETABLE_VIRT_START, max_page);
 
-    initial_images_start = MAX_DIRECTMAP_ADDRESS;
+    /* Initial images stashed away above DIRECTMAP area in boot.S. */
+    initial_images_start = DIRECTMAP_PHYS_END;
     initial_images_end   = initial_images_start + 
         (mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
+
+#elif defined(__x86_64__)
+
+    init_frametable(__va(xenheap_phys_end), max_page);
+
+    initial_images_start = __pa(frame_table) + frame_table_size;
+    initial_images_end   = initial_images_start + 
+        (mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
+    if ( initial_images_end > (max_page << PAGE_SHIFT) )
+    {
+        printk("Not enough memory to stash the DOM0 kernel image.\n");
+        for ( ; ; ) ;
+    }
+    memmove(__va(initial_images_start),
+            __va(mod[0].mod_start),
+            mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
+
+#endif
+
     dom0_memory_start    = (initial_images_end + ((4<<20)-1)) & ~((4<<20)-1);
     dom0_memory_end      = dom0_memory_start + (opt_dom0_mem << 10);
     dom0_memory_end      = (dom0_memory_end + PAGE_SIZE - 1) & PAGE_MASK;
     
     /* Cheesy sanity check: enough memory for DOM0 allocation + some slack? */
-    if ( (dom0_memory_end + (8<<20)) > (max_page<<PAGE_SHIFT) )
-        panic("Not enough memory to craete initial domain!\n");
+    if ( (dom0_memory_end + (8<<20)) > (max_page << PAGE_SHIFT) )
+    {
+        printk("Not enough memory for DOM0 memory reservation.\n");
+        for ( ; ; ) ;
+    }
+
+    printk("Initialised %luMB memory (%lu pages) on a %luMB machine\n",
+           max_page >> (20-PAGE_SHIFT), max_page,
+          max_mem  >> (20-PAGE_SHIFT));
 
     add_to_domain_alloc_list(dom0_memory_end, max_page << PAGE_SHIFT);
 
     heap_start = memguard_init(&_end);
 
     printk("Xen heap size is %luKB\n", 
-          (MAX_XENHEAP_ADDRESS-__pa(heap_start))/1024 );
-
-    if ( ((MAX_XENHEAP_ADDRESS-__pa(heap_start))/1024) <= 4096 )
-    {
-        printk("Xen heap size is too small to safely continue!\n");
-        for ( ; ; ) ;
-    }
+          (xenheap_phys_end-__pa(heap_start))/1024 );
 
-    init_page_allocator(__pa(heap_start), MAX_XENHEAP_ADDRESS);
+    init_page_allocator(__pa(heap_start), xenheap_phys_end);
  
     /* Initialise the slab allocator. */
     kmem_cache_init();
@@ -253,8 +287,7 @@ void cmain(unsigned long magic, multiboot_info_t *mbi)
 
     /*
      * We're going to setup domain0 using the module(s) that we stashed safely
-     * above our MAX_DIRECTMAP_ADDRESS in boot/boot.S. The second module, if
-     * present, is an initrd ramdisk.
+     * above our heap. The second module, if present, is an initrd ramdisk.
      */
     if ( construct_dom0(new_dom, dom0_memory_start, dom0_memory_end,
                         (char *)initial_images_start, 
index 08e0b052857ba93a9129ae40003766a1eb3951ac..4675a95d2e9969f3329689f3273d9547f5ce9af3 100644 (file)
@@ -144,7 +144,7 @@ static struct {
 #define GPS (percpu_info[smp_processor_id()].gps ? : current)
 
 
-void __init init_frametable(unsigned long nr_pages)
+void __init init_frametable(void *frametable_vstart, unsigned long nr_pages)
 {
     unsigned long mfn;
 
@@ -153,22 +153,23 @@ void __init init_frametable(unsigned long nr_pages)
     max_page = nr_pages;
     frame_table_size = nr_pages * sizeof(struct pfn_info);
     frame_table_size = (frame_table_size + PAGE_SIZE - 1) & PAGE_MASK;
-    frame_table = (struct pfn_info *)FRAMETABLE_VIRT_START;
+    frame_table = frametable_vstart;
+
+    if ( (__pa(frame_table) + frame_table_size) > (max_page << PAGE_SHIFT) )
+        panic("Not enough memory for frame table - reduce Xen heap size?\n");
+
     memset(frame_table, 0, frame_table_size);
 
     spin_lock_init(&free_list_lock);
     INIT_LIST_HEAD(&free_list);    
     free_pfns = 0;
 
-    /* initialise to a magic of 0x55555555 so easier to spot bugs later */
-    memset( machine_to_phys_mapping, 0x55, 4*1024*1024 );
-
-    /* The array is sized for a 4GB machine regardless of actuall mem size. 
-       This costs 4MB -- may want to fix some day */
+    /* Initialise to a magic of 0x55555555 so easier to spot bugs later. */
+    memset(machine_to_phys_mapping, 0x55, 4<<20);
 
     /* Pin the ownership of the MP table so that DOM0 can map it later. */
-    for ( mfn = virt_to_phys(&machine_to_phys_mapping[0])>>PAGE_SHIFT;
-          mfn < virt_to_phys(&machine_to_phys_mapping[1024*1024])>>PAGE_SHIFT;
+    for ( mfn = virt_to_phys(&machine_to_phys_mapping[0<<20])>>PAGE_SHIFT;
+          mfn < virt_to_phys(&machine_to_phys_mapping[1<<20])>>PAGE_SHIFT;
           mfn++ )
     {
         frame_table[mfn].count_and_flags = 1 | PGC_allocated;
@@ -471,6 +472,7 @@ static int alloc_l2_table(struct pfn_info *page)
         if ( unlikely(!get_page_from_l2e(pl2e[i], page_nr)) )
             goto fail;
     
+#if defined(__i386__)
     /* Now we add our private high mappings. */
     memcpy(&pl2e[DOMAIN_ENTRIES_PER_L2_PAGETABLE], 
            &idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
@@ -480,6 +482,7 @@ static int alloc_l2_table(struct pfn_info *page)
     pl2e[PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT] =
         mk_l2_pgentry(__pa(page->u.domain->mm.perdomain_pt) | 
                       __PAGE_HYPERVISOR);
+#endif
 
     unmap_domain_mem(pl2e);
     return 1;
index de5fe4b4fa7085dea2945b37dba46b2f2981cef9..dc08bd0199d85ff048e281d7d342c22de100dde4 100644 (file)
@@ -151,7 +151,9 @@ static inline int shadow_page_op( struct mm_struct *m, unsigned int op,
              PGT_l2_page_table )
                {
                        unsigned long * spl1e = map_domain_mem( spfn<<PAGE_SHIFT );
-                       memset( spl1e, 0, DOMAIN_ENTRIES_PER_L2_PAGETABLE * sizeof(*spl1e) );
+#ifdef __i386__
+                       memset(spl1e, 0, DOMAIN_ENTRIES_PER_L2_PAGETABLE * sizeof(*spl1e));
+#endif
                        unmap_domain_mem( spl1e );
                }
     }
@@ -574,6 +576,7 @@ unsigned long shadow_l2_table(
     // we need to do this before the linear map is set up
     spl2e = (l2_pgentry_t *) map_domain_mem(spfn << PAGE_SHIFT);
 
+#ifdef __i386__
     // get hypervisor and 2x linear PT mapings installed 
     memcpy(&spl2e[DOMAIN_ENTRIES_PER_L2_PAGETABLE], 
            &idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
@@ -585,6 +588,7 @@ unsigned long shadow_l2_table(
     spl2e[PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT] =
         mk_l2_pgentry(__pa(frame_table[gpfn].u.domain->mm.perdomain_pt) | 
                       __PAGE_HYPERVISOR);
+#endif
 
     // can't use the linear map as we may not be in the right PT
     gpl2e = (l2_pgentry_t *) map_domain_mem(gpfn << PAGE_SHIFT);
index c38304ab8b8fdc436d3c5df36cdf66372a08057c..af0172df90efd6670850521b4d0e64d61ff1df46 100644 (file)
@@ -93,6 +93,8 @@ extern void __out_of_line_bug(int line) __attribute__((noreturn));
 
 #if defined(__x86_64__)
 
+#define XENHEAP_DEFAULT_MB (16)
+
 #define PML4_ENTRY_BITS  39
 #define PML4_ENTRY_BYTES (1UL<<PML4_ENTRY_BITS)
 
@@ -158,9 +160,8 @@ extern void __out_of_line_bug(int line) __attribute__((noreturn));
 
 #elif defined(__i386__)
 
-/* The following are machine addresses. */
-#define MAX_XENHEAP_ADDRESS   (12*1024*1024)
-#define MAX_DIRECTMAP_ADDRESS (40*1024*1024)
+#define XENHEAP_DEFAULT_MB (12)
+#define DIRECTMAP_PHYS_END (40*1024*1024)
 
 /* Hypervisor owns top 64MB of virtual address space. */
 #define HYPERVISOR_VIRT_START (0xFC000000UL)
@@ -173,9 +174,9 @@ extern void __out_of_line_bug(int line) __attribute__((noreturn));
 #define RO_MPT_VIRT_END       (RO_MPT_VIRT_START + (4*1024*1024))
 /* The virtual addresses for the 40MB direct-map region. */
 #define DIRECTMAP_VIRT_START  (RO_MPT_VIRT_END)
-#define DIRECTMAP_VIRT_END    (DIRECTMAP_VIRT_START + MAX_DIRECTMAP_ADDRESS)
+#define DIRECTMAP_VIRT_END    (DIRECTMAP_VIRT_START + DIRECTMAP_PHYS_END)
 #define XENHEAP_VIRT_START    (DIRECTMAP_VIRT_START)
-#define XENHEAP_VIRT_END      (XENHEAP_VIRT_START + MAX_XENHEAP_ADDRESS)
+#define XENHEAP_VIRT_END      (XENHEAP_VIRT_START + (XENHEAP_DEFAULT_MB<<20))
 #define RDWR_MPT_VIRT_START   (XENHEAP_VIRT_END)
 #define RDWR_MPT_VIRT_END     (RDWR_MPT_VIRT_START + (4*1024*1024))
 #define FRAMETABLE_VIRT_START (RDWR_MPT_VIRT_END)
@@ -207,6 +208,10 @@ extern void __out_of_line_bug(int line) __attribute__((noreturn));
 
 #endif /* __i386__ */
 
+#ifndef __ASSEMBLY__
+extern unsigned long xenheap_phys_end; /* user-configurable */
+#endif
+
 #define GDT_VIRT_START        (PERDOMAIN_VIRT_START)
 #define GDT_VIRT_END          (GDT_VIRT_START + (64*1024))
 #define LDT_VIRT_START        (GDT_VIRT_END)
index 95cbb4b5145a53f6cafbe98701452ea16837cbc6..8eb30e35ea3c041185f44d47f9f8fd549992cb34 100644 (file)
@@ -95,12 +95,12 @@ typedef struct { unsigned long pt_lo; } pagetable_t;
 extern l2_pgentry_t idle_pg_table[ENTRIES_PER_L2_PAGETABLE];
 extern void paging_init(void);
 
-#define __flush_tlb()                                    \
-    do {                                                 \
-        __asm__ __volatile__ (                           \
-            "movl %%cr3, %%eax; movl %%eax, %%cr3"       \
-            : : : "memory", "eax" );                     \
-        tlb_clocktick();                                 \
+#define __flush_tlb()                                             \
+    do {                                                          \
+        __asm__ __volatile__ (                                    \
+            "mov %%cr3, %%"__OP"ax; mov %%"__OP"ax, %%cr3"        \
+            : : : "memory", __OP"ax" );                           \
+        tlb_clocktick();                                          \
     } while ( 0 )
 
 /* Flush global pages as well. */
@@ -108,14 +108,14 @@ extern void paging_init(void);
 #define __pge_off()                                                     \
         do {                                                            \
                 __asm__ __volatile__(                                   \
-                        "movl %0, %%cr4;  # turn off PGE     "          \
+                        "mov %0, %%cr4;  # turn off PGE     "           \
                         :: "r" (mmu_cr4_features & ~X86_CR4_PGE));      \
         } while (0)
 
 #define __pge_on()                                                      \
         do {                                                            \
                 __asm__ __volatile__(                                   \
-                        "movl %0, %%cr4;  # turn off PGE     "          \
+                        "mov %0, %%cr4;  # turn off PGE     "           \
                         :: "r" (mmu_cr4_features));                     \
         } while (0)
 
index 27fbb4d035b517170d75e3c09f26bd81a0212e23..fd7ae02a853bcca83ff30ff30346211cc48e778a 100644 (file)
@@ -1,485 +1,5 @@
-#ifndef _I386_STRING_H_
-#define _I386_STRING_H_
-
-#include <xen/config.h>
-
-/*
- * This string-include defines all string functions as inline
- * functions. Use gcc. It also assumes ds=es=data space, this should be
- * normal. Most of the string-functions are rather heavily hand-optimized,
- * see especially strtok,strstr,str[c]spn. They should work, but are not
- * very easy to understand. Everything is done entirely within the register
- * set, making the functions fast and clean. String instructions have been
- * used through-out, making for "slightly" unclear code :-)
- *
- *             NO Copyright (C) 1991, 1992 Linus Torvalds,
- *             consider these trivial functions to be PD.
- */
-
-
-#define __HAVE_ARCH_STRCPY
-static inline char * strcpy(char * dest,const char *src)
-{
-int d0, d1, d2;
-__asm__ __volatile__(
-       "1:\tlodsb\n\t"
-       "stosb\n\t"
-       "testb %%al,%%al\n\t"
-       "jne 1b"
-       : "=&S" (d0), "=&D" (d1), "=&a" (d2)
-       :"0" (src),"1" (dest) : "memory");
-return dest;
-}
-
-#define __HAVE_ARCH_STRNCPY
-static inline char * strncpy(char * dest,const char *src,size_t count)
-{
-int d0, d1, d2, d3;
-__asm__ __volatile__(
-       "1:\tdecl %2\n\t"
-       "js 2f\n\t"
-       "lodsb\n\t"
-       "stosb\n\t"
-       "testb %%al,%%al\n\t"
-       "jne 1b\n\t"
-       "rep\n\t"
-       "stosb\n"
-       "2:"
-       : "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
-       :"0" (src),"1" (dest),"2" (count) : "memory");
-return dest;
-}
-
-#define __HAVE_ARCH_STRCAT
-static inline char * strcat(char * dest,const char * src)
-{
-int d0, d1, d2, d3;
-__asm__ __volatile__(
-       "repne\n\t"
-       "scasb\n\t"
-       "decl %1\n"
-       "1:\tlodsb\n\t"
-       "stosb\n\t"
-       "testb %%al,%%al\n\t"
-       "jne 1b"
-       : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
-       : "0" (src), "1" (dest), "2" (0), "3" (0xffffffff):"memory");
-return dest;
-}
-
-#define __HAVE_ARCH_STRNCAT
-static inline char * strncat(char * dest,const char * src,size_t count)
-{
-int d0, d1, d2, d3;
-__asm__ __volatile__(
-       "repne\n\t"
-       "scasb\n\t"
-       "decl %1\n\t"
-       "movl %8,%3\n"
-       "1:\tdecl %3\n\t"
-       "js 2f\n\t"
-       "lodsb\n\t"
-       "stosb\n\t"
-       "testb %%al,%%al\n\t"
-       "jne 1b\n"
-       "2:\txorl %2,%2\n\t"
-       "stosb"
-       : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
-       : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
-       : "memory");
-return dest;
-}
-
-#define __HAVE_ARCH_STRCMP
-static inline int strcmp(const char * cs,const char * ct)
-{
-int d0, d1;
-register int __res;
-__asm__ __volatile__(
-       "1:\tlodsb\n\t"
-       "scasb\n\t"
-       "jne 2f\n\t"
-       "testb %%al,%%al\n\t"
-       "jne 1b\n\t"
-       "xorl %%eax,%%eax\n\t"
-       "jmp 3f\n"
-       "2:\tsbbl %%eax,%%eax\n\t"
-       "orb $1,%%al\n"
-       "3:"
-       :"=a" (__res), "=&S" (d0), "=&D" (d1)
-                    :"1" (cs),"2" (ct));
-return __res;
-}
-
-#define __HAVE_ARCH_STRNCMP
-static inline int strncmp(const char * cs,const char * ct,size_t count)
-{
-register int __res;
-int d0, d1, d2;
-__asm__ __volatile__(
-       "1:\tdecl %3\n\t"
-       "js 2f\n\t"
-       "lodsb\n\t"
-       "scasb\n\t"
-       "jne 3f\n\t"
-       "testb %%al,%%al\n\t"
-       "jne 1b\n"
-       "2:\txorl %%eax,%%eax\n\t"
-       "jmp 4f\n"
-       "3:\tsbbl %%eax,%%eax\n\t"
-       "orb $1,%%al\n"
-       "4:"
-                    :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
-                    :"1" (cs),"2" (ct),"3" (count));
-return __res;
-}
-
-#define __HAVE_ARCH_STRCHR
-static inline char * strchr(const char * s, int c)
-{
-int d0;
-register char * __res;
-__asm__ __volatile__(
-       "movb %%al,%%ah\n"
-       "1:\tlodsb\n\t"
-       "cmpb %%ah,%%al\n\t"
-       "je 2f\n\t"
-       "testb %%al,%%al\n\t"
-       "jne 1b\n\t"
-       "movl $1,%1\n"
-       "2:\tmovl %1,%0\n\t"
-       "decl %0"
-       :"=a" (__res), "=&S" (d0) : "1" (s),"0" (c));
-return __res;
-}
-
-#define __HAVE_ARCH_STRRCHR
-static inline char * strrchr(const char * s, int c)
-{
-int d0, d1;
-register char * __res;
-__asm__ __volatile__(
-       "movb %%al,%%ah\n"
-       "1:\tlodsb\n\t"
-       "cmpb %%ah,%%al\n\t"
-       "jne 2f\n\t"
-       "leal -1(%%esi),%0\n"
-       "2:\ttestb %%al,%%al\n\t"
-       "jne 1b"
-       :"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c));
-return __res;
-}
-
-#define __HAVE_ARCH_STRLEN
-static inline size_t strlen(const char * s)
-{
-int d0;
-register int __res;
-__asm__ __volatile__(
-       "repne\n\t"
-       "scasb\n\t"
-       "notl %0\n\t"
-       "decl %0"
-       :"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff));
-return __res;
-}
-
-static inline void * __memcpy(void * to, const void * from, size_t n)
-{
-int d0, d1, d2;
-__asm__ __volatile__(
-       "rep ; movsl\n\t"
-       "testb $2,%b4\n\t"
-       "je 1f\n\t"
-       "movsw\n"
-       "1:\ttestb $1,%b4\n\t"
-       "je 2f\n\t"
-       "movsb\n"
-       "2:"
-       : "=&c" (d0), "=&D" (d1), "=&S" (d2)
-       :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
-       : "memory");
-return (to);
-}
-
-/*
- * This looks horribly ugly, but the compiler can optimize it totally,
- * as the count is constant.
- */
-static inline void * __constant_memcpy(void * to, const void * from, size_t n)
-{
-       switch (n) {
-               case 0:
-                       return to;
-               case 1:
-                       *(unsigned char *)to = *(const unsigned char *)from;
-                       return to;
-               case 2:
-                       *(unsigned short *)to = *(const unsigned short *)from;
-                       return to;
-               case 3:
-                       *(unsigned short *)to = *(const unsigned short *)from;
-                       *(2+(unsigned char *)to) = *(2+(const unsigned char *)from);
-                       return to;
-               case 4:
-                       *(unsigned long *)to = *(const unsigned long *)from;
-                       return to;
-               case 6: /* for Ethernet addresses */
-                       *(unsigned long *)to = *(const unsigned long *)from;
-                       *(2+(unsigned short *)to) = *(2+(const unsigned short *)from);
-                       return to;
-               case 8:
-                       *(unsigned long *)to = *(const unsigned long *)from;
-                       *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
-                       return to;
-               case 12:
-                       *(unsigned long *)to = *(const unsigned long *)from;
-                       *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
-                       *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
-                       return to;
-               case 16:
-                       *(unsigned long *)to = *(const unsigned long *)from;
-                       *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
-                       *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
-                       *(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
-                       return to;
-               case 20:
-                       *(unsigned long *)to = *(const unsigned long *)from;
-                       *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
-                       *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
-                       *(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
-                       *(4+(unsigned long *)to) = *(4+(const unsigned long *)from);
-                       return to;
-       }
-#define COMMON(x) \
-__asm__ __volatile__( \
-       "rep ; movsl" \
-       x \
-       : "=&c" (d0), "=&D" (d1), "=&S" (d2) \
-       : "0" (n/4),"1" ((long) to),"2" ((long) from) \
-       : "memory");
-{
-       int d0, d1, d2;
-       switch (n % 4) {
-               case 0: COMMON(""); return to;
-               case 1: COMMON("\n\tmovsb"); return to;
-               case 2: COMMON("\n\tmovsw"); return to;
-               default: COMMON("\n\tmovsw\n\tmovsb"); return to;
-       }
-}
-  
-#undef COMMON
-}
-
-#define __HAVE_ARCH_MEMCPY
-
-#define memcpy(t, f, n) \
-(__builtin_constant_p(n) ? \
- __constant_memcpy((t),(f),(n)) : \
- __memcpy((t),(f),(n)))
-
-
-/*
- * struct_cpy(x,y), copy structure *x into (matching structure) *y.
- *
- * We get link-time errors if the structure sizes do not match.
- * There is no runtime overhead, it's all optimized away at
- * compile time.
- */
-//extern void __struct_cpy_bug (void);
-
-/*
-#define struct_cpy(x,y)                        \
-({                                             \
-       if (sizeof(*(x)) != sizeof(*(y)))       \
-               __struct_cpy_bug;               \
-       memcpy(x, y, sizeof(*(x)));             \
-})
-*/
-
-#define __HAVE_ARCH_MEMMOVE
-static inline void * memmove(void * dest,const void * src, size_t n)
-{
-int d0, d1, d2;
-if (dest<src)
-__asm__ __volatile__(
-       "rep\n\t"
-       "movsb"
-       : "=&c" (d0), "=&S" (d1), "=&D" (d2)
-       :"0" (n),"1" (src),"2" (dest)
-       : "memory");
-else
-__asm__ __volatile__(
-       "std\n\t"
-       "rep\n\t"
-       "movsb\n\t"
-       "cld"
-       : "=&c" (d0), "=&S" (d1), "=&D" (d2)
-       :"0" (n),
-        "1" (n-1+(const char *)src),
-        "2" (n-1+(char *)dest)
-       :"memory");
-return dest;
-}
-
-#define __HAVE_ARCH_MEMCMP
-#define memcmp __builtin_memcmp
-
-#define __HAVE_ARCH_MEMCHR
-static inline void * memchr(const void * cs,int c,size_t count)
-{
-int d0;
-register void * __res;
-if (!count)
-       return NULL;
-__asm__ __volatile__(
-       "repne\n\t"
-       "scasb\n\t"
-       "je 1f\n\t"
-       "movl $1,%0\n"
-       "1:\tdecl %0"
-       :"=D" (__res), "=&c" (d0) : "a" (c),"0" (cs),"1" (count));
-return __res;
-}
-
-static inline void * __memset_generic(void * s, char c,size_t count)
-{
-int d0, d1;
-__asm__ __volatile__(
-       "rep\n\t"
-       "stosb"
-       : "=&c" (d0), "=&D" (d1)
-       :"a" (c),"1" (s),"0" (count)
-       :"memory");
-return s;
-}
-
-/* we might want to write optimized versions of these later */
-#define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
-
-/*
- * memset(x,0,y) is a reasonably common thing to do, so we want to fill
- * things 32 bits at a time even when we don't know the size of the
- * area at compile-time..
- */
-static inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
-{
-int d0, d1;
-__asm__ __volatile__(
-       "rep ; stosl\n\t"
-       "testb $2,%b3\n\t"
-       "je 1f\n\t"
-       "stosw\n"
-       "1:\ttestb $1,%b3\n\t"
-       "je 2f\n\t"
-       "stosb\n"
-       "2:"
-       : "=&c" (d0), "=&D" (d1)
-       :"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
-       :"memory");
-return (s);    
-}
-
-/* Added by Gertjan van Wingerde to make minix and sysv module work */
-#define __HAVE_ARCH_STRNLEN
-static inline size_t strnlen(const char * s, size_t count)
-{
-int d0;
-register int __res;
-__asm__ __volatile__(
-       "movl %2,%0\n\t"
-       "jmp 2f\n"
-       "1:\tcmpb $0,(%0)\n\t"
-       "je 3f\n\t"
-       "incl %0\n"
-       "2:\tdecl %1\n\t"
-       "cmpl $-1,%1\n\t"
-       "jne 1b\n"
-       "3:\tsubl %2,%0"
-       :"=a" (__res), "=&d" (d0)
-       :"c" (s),"1" (count));
-return __res;
-}
-/* end of additional stuff */
-
-//#define __HAVE_ARCH_STRSTR
-
-//extern char *strstr(const char *cs, const char *ct);
-
-/*
- * This looks horribly ugly, but the compiler can optimize it totally,
- * as we by now know that both pattern and count is constant..
- */
-static inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
-{
-       switch (count) {
-               case 0:
-                       return s;
-               case 1:
-                       *(unsigned char *)s = pattern;
-                       return s;
-               case 2:
-                       *(unsigned short *)s = pattern;
-                       return s;
-               case 3:
-                       *(unsigned short *)s = pattern;
-                       *(2+(unsigned char *)s) = pattern;
-                       return s;
-               case 4:
-                       *(unsigned long *)s = pattern;
-                       return s;
-       }
-#define COMMON(x) \
-__asm__  __volatile__( \
-       "rep ; stosl" \
-       x \
-       : "=&c" (d0), "=&D" (d1) \
-       : "a" (pattern),"0" (count/4),"1" ((long) s) \
-       : "memory")
-{
-       int d0, d1;
-       switch (count % 4) {
-               case 0: COMMON(""); return s;
-               case 1: COMMON("\n\tstosb"); return s;
-               case 2: COMMON("\n\tstosw"); return s;
-               default: COMMON("\n\tstosw\n\tstosb"); return s;
-       }
-}
-  
-#undef COMMON
-}
-
-#define __constant_c_x_memset(s, c, count) \
-(__builtin_constant_p(count) ? \
- __constant_c_and_count_memset((s),(c),(count)) : \
- __constant_c_memset((s),(c),(count)))
-
-#define __memset(s, c, count) \
-(__builtin_constant_p(count) ? \
- __constant_count_memset((s),(c),(count)) : \
- __memset_generic((s),(c),(count)))
-
-#define __HAVE_ARCH_MEMSET
-#define memset(s, c, count) \
-(__builtin_constant_p(c) ? \
- __constant_c_x_memset((s),(0x01010101UL*(unsigned char)(c)),(count)) : \
- __memset((s),(c),(count)))
-
-/*
- * find the first occurrence of byte 'c', or 1 past the area if none
- */
-#define __HAVE_ARCH_MEMSCAN
-static inline void * memscan(void * addr, int c, size_t size)
-{
-       if (!size)
-               return addr;
-       __asm__("repnz; scasb\n\t"
-               "jnz 1f\n\t"
-               "dec %%edi\n"
-               "1:"
-               : "=D" (addr), "=c" (size)
-               : "0" (addr), "1" (size), "a" (c));
-       return addr;
-}
-
+#ifdef __x86_64__
+#include <asm/x86_64/string.h>
+#else
+#include <asm/x86_32/string.h>
 #endif
index 0b4b616b245b1177bc94a2d869235fae4c7627ec..e2b229edcfa1182ec943aa3daab9dca6bf6979d5 100644 (file)
@@ -3,7 +3,6 @@
 
 typedef unsigned short umode_t;
 
-typedef unsigned int size_t;
 
 /*
  * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
@@ -44,10 +43,12 @@ typedef unsigned int u32;
 typedef signed long long s64;
 typedef unsigned long long u64;
 #define BITS_PER_LONG 32
+typedef unsigned int size_t;
 #elif defined(__x86_64__)
 typedef signed long s64;
 typedef unsigned long u64;
 #define BITS_PER_LONG 64
+typedef unsigned long size_t;
 #endif
 
 /* DMA addresses come in generic and 64-bit flavours.  */
diff --git a/xen/include/asm-x86/x86_32/string.h b/xen/include/asm-x86/x86_32/string.h
new file mode 100644 (file)
index 0000000..27fbb4d
--- /dev/null
@@ -0,0 +1,485 @@
+#ifndef _I386_STRING_H_
+#define _I386_STRING_H_
+
+#include <xen/config.h>
+
+/*
+ * This string-include defines all string functions as inline
+ * functions. Use gcc. It also assumes ds=es=data space, this should be
+ * normal. Most of the string-functions are rather heavily hand-optimized,
+ * see especially strtok,strstr,str[c]spn. They should work, but are not
+ * very easy to understand. Everything is done entirely within the register
+ * set, making the functions fast and clean. String instructions have been
+ * used through-out, making for "slightly" unclear code :-)
+ *
+ *             NO Copyright (C) 1991, 1992 Linus Torvalds,
+ *             consider these trivial functions to be PD.
+ */
+
+
+#define __HAVE_ARCH_STRCPY
+static inline char * strcpy(char * dest,const char *src)
+{
+int d0, d1, d2;
+__asm__ __volatile__(
+       "1:\tlodsb\n\t"
+       "stosb\n\t"
+       "testb %%al,%%al\n\t"
+       "jne 1b"
+       : "=&S" (d0), "=&D" (d1), "=&a" (d2)
+       :"0" (src),"1" (dest) : "memory");
+return dest;
+}
+
+#define __HAVE_ARCH_STRNCPY
+static inline char * strncpy(char * dest,const char *src,size_t count)
+{
+int d0, d1, d2, d3;
+__asm__ __volatile__(
+       "1:\tdecl %2\n\t"
+       "js 2f\n\t"
+       "lodsb\n\t"
+       "stosb\n\t"
+       "testb %%al,%%al\n\t"
+       "jne 1b\n\t"
+       "rep\n\t"
+       "stosb\n"
+       "2:"
+       : "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
+       :"0" (src),"1" (dest),"2" (count) : "memory");
+return dest;
+}
+
+#define __HAVE_ARCH_STRCAT
+static inline char * strcat(char * dest,const char * src)
+{
+int d0, d1, d2, d3;
+__asm__ __volatile__(
+       "repne\n\t"
+       "scasb\n\t"
+       "decl %1\n"
+       "1:\tlodsb\n\t"
+       "stosb\n\t"
+       "testb %%al,%%al\n\t"
+       "jne 1b"
+       : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
+       : "0" (src), "1" (dest), "2" (0), "3" (0xffffffff):"memory");
+return dest;
+}
+
+#define __HAVE_ARCH_STRNCAT
+static inline char * strncat(char * dest,const char * src,size_t count)
+{
+int d0, d1, d2, d3;
+__asm__ __volatile__(
+       "repne\n\t"
+       "scasb\n\t"
+       "decl %1\n\t"
+       "movl %8,%3\n"
+       "1:\tdecl %3\n\t"
+       "js 2f\n\t"
+       "lodsb\n\t"
+       "stosb\n\t"
+       "testb %%al,%%al\n\t"
+       "jne 1b\n"
+       "2:\txorl %2,%2\n\t"
+       "stosb"
+       : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
+       : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
+       : "memory");
+return dest;
+}
+
+#define __HAVE_ARCH_STRCMP
+static inline int strcmp(const char * cs,const char * ct)
+{
+int d0, d1;
+register int __res;
+__asm__ __volatile__(
+       "1:\tlodsb\n\t"
+       "scasb\n\t"
+       "jne 2f\n\t"
+       "testb %%al,%%al\n\t"
+       "jne 1b\n\t"
+       "xorl %%eax,%%eax\n\t"
+       "jmp 3f\n"
+       "2:\tsbbl %%eax,%%eax\n\t"
+       "orb $1,%%al\n"
+       "3:"
+       :"=a" (__res), "=&S" (d0), "=&D" (d1)
+                    :"1" (cs),"2" (ct));
+return __res;
+}
+
+#define __HAVE_ARCH_STRNCMP
+static inline int strncmp(const char * cs,const char * ct,size_t count)
+{
+register int __res;
+int d0, d1, d2;
+__asm__ __volatile__(
+       "1:\tdecl %3\n\t"
+       "js 2f\n\t"
+       "lodsb\n\t"
+       "scasb\n\t"
+       "jne 3f\n\t"
+       "testb %%al,%%al\n\t"
+       "jne 1b\n"
+       "2:\txorl %%eax,%%eax\n\t"
+       "jmp 4f\n"
+       "3:\tsbbl %%eax,%%eax\n\t"
+       "orb $1,%%al\n"
+       "4:"
+                    :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
+                    :"1" (cs),"2" (ct),"3" (count));
+return __res;
+}
+
+#define __HAVE_ARCH_STRCHR
+static inline char * strchr(const char * s, int c)
+{
+int d0;
+register char * __res;
+__asm__ __volatile__(
+       "movb %%al,%%ah\n"
+       "1:\tlodsb\n\t"
+       "cmpb %%ah,%%al\n\t"
+       "je 2f\n\t"
+       "testb %%al,%%al\n\t"
+       "jne 1b\n\t"
+       "movl $1,%1\n"
+       "2:\tmovl %1,%0\n\t"
+       "decl %0"
+       :"=a" (__res), "=&S" (d0) : "1" (s),"0" (c));
+return __res;
+}
+
+#define __HAVE_ARCH_STRRCHR
+static inline char * strrchr(const char * s, int c)
+{
+int d0, d1;
+register char * __res;
+__asm__ __volatile__(
+       "movb %%al,%%ah\n"
+       "1:\tlodsb\n\t"
+       "cmpb %%ah,%%al\n\t"
+       "jne 2f\n\t"
+       "leal -1(%%esi),%0\n"
+       "2:\ttestb %%al,%%al\n\t"
+       "jne 1b"
+       :"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c));
+return __res;
+}
+
+#define __HAVE_ARCH_STRLEN
+static inline size_t strlen(const char * s)
+{
+int d0;
+register int __res;
+__asm__ __volatile__(
+       "repne\n\t"
+       "scasb\n\t"
+       "notl %0\n\t"
+       "decl %0"
+       :"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff));
+return __res;
+}
+
+static inline void * __memcpy(void * to, const void * from, size_t n)
+{
+int d0, d1, d2;
+__asm__ __volatile__(
+       "rep ; movsl\n\t"
+       "testb $2,%b4\n\t"
+       "je 1f\n\t"
+       "movsw\n"
+       "1:\ttestb $1,%b4\n\t"
+       "je 2f\n\t"
+       "movsb\n"
+       "2:"
+       : "=&c" (d0), "=&D" (d1), "=&S" (d2)
+       :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
+       : "memory");
+return (to);
+}
+
+/*
+ * This looks horribly ugly, but the compiler can optimize it totally,
+ * as the count is constant.
+ */
+static inline void * __constant_memcpy(void * to, const void * from, size_t n)
+{
+       switch (n) {
+               case 0:
+                       return to;
+               case 1:
+                       *(unsigned char *)to = *(const unsigned char *)from;
+                       return to;
+               case 2:
+                       *(unsigned short *)to = *(const unsigned short *)from;
+                       return to;
+               case 3:
+                       *(unsigned short *)to = *(const unsigned short *)from;
+                       *(2+(unsigned char *)to) = *(2+(const unsigned char *)from);
+                       return to;
+               case 4:
+                       *(unsigned long *)to = *(const unsigned long *)from;
+                       return to;
+               case 6: /* for Ethernet addresses */
+                       *(unsigned long *)to = *(const unsigned long *)from;
+                       *(2+(unsigned short *)to) = *(2+(const unsigned short *)from);
+                       return to;
+               case 8:
+                       *(unsigned long *)to = *(const unsigned long *)from;
+                       *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
+                       return to;
+               case 12:
+                       *(unsigned long *)to = *(const unsigned long *)from;
+                       *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
+                       *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
+                       return to;
+               case 16:
+                       *(unsigned long *)to = *(const unsigned long *)from;
+                       *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
+                       *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
+                       *(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
+                       return to;
+               case 20:
+                       *(unsigned long *)to = *(const unsigned long *)from;
+                       *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
+                       *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
+                       *(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
+                       *(4+(unsigned long *)to) = *(4+(const unsigned long *)from);
+                       return to;
+       }
+#define COMMON(x) \
+__asm__ __volatile__( \
+       "rep ; movsl" \
+       x \
+       : "=&c" (d0), "=&D" (d1), "=&S" (d2) \
+       : "0" (n/4),"1" ((long) to),"2" ((long) from) \
+       : "memory");
+{
+       int d0, d1, d2;
+       switch (n % 4) {
+               case 0: COMMON(""); return to;
+               case 1: COMMON("\n\tmovsb"); return to;
+               case 2: COMMON("\n\tmovsw"); return to;
+               default: COMMON("\n\tmovsw\n\tmovsb"); return to;
+       }
+}
+  
+#undef COMMON
+}
+
+#define __HAVE_ARCH_MEMCPY
+
+#define memcpy(t, f, n) \
+(__builtin_constant_p(n) ? \
+ __constant_memcpy((t),(f),(n)) : \
+ __memcpy((t),(f),(n)))
+
+
+/*
+ * struct_cpy(x,y), copy structure *x into (matching structure) *y.
+ *
+ * We get link-time errors if the structure sizes do not match.
+ * There is no runtime overhead, it's all optimized away at
+ * compile time.
+ */
+//extern void __struct_cpy_bug (void);
+
+/*
+#define struct_cpy(x,y)                        \
+({                                             \
+       if (sizeof(*(x)) != sizeof(*(y)))       \
+               __struct_cpy_bug;               \
+       memcpy(x, y, sizeof(*(x)));             \
+})
+*/
+
+#define __HAVE_ARCH_MEMMOVE
+static inline void * memmove(void * dest,const void * src, size_t n)
+{
+int d0, d1, d2;
+if (dest<src)
+__asm__ __volatile__(
+       "rep\n\t"
+       "movsb"
+       : "=&c" (d0), "=&S" (d1), "=&D" (d2)
+       :"0" (n),"1" (src),"2" (dest)
+       : "memory");
+else
+__asm__ __volatile__(
+       "std\n\t"
+       "rep\n\t"
+       "movsb\n\t"
+       "cld"
+       : "=&c" (d0), "=&S" (d1), "=&D" (d2)
+       :"0" (n),
+        "1" (n-1+(const char *)src),
+        "2" (n-1+(char *)dest)
+       :"memory");
+return dest;
+}
+
+#define __HAVE_ARCH_MEMCMP
+#define memcmp __builtin_memcmp
+
+#define __HAVE_ARCH_MEMCHR
+static inline void * memchr(const void * cs,int c,size_t count)
+{
+int d0;
+register void * __res;
+if (!count)
+       return NULL;
+__asm__ __volatile__(
+       "repne\n\t"
+       "scasb\n\t"
+       "je 1f\n\t"
+       "movl $1,%0\n"
+       "1:\tdecl %0"
+       :"=D" (__res), "=&c" (d0) : "a" (c),"0" (cs),"1" (count));
+return __res;
+}
+
+static inline void * __memset_generic(void * s, char c,size_t count)
+{
+int d0, d1;
+__asm__ __volatile__(
+       "rep\n\t"
+       "stosb"
+       : "=&c" (d0), "=&D" (d1)
+       :"a" (c),"1" (s),"0" (count)
+       :"memory");
+return s;
+}
+
+/* we might want to write optimized versions of these later */
+#define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
+
+/*
+ * memset(x,0,y) is a reasonably common thing to do, so we want to fill
+ * things 32 bits at a time even when we don't know the size of the
+ * area at compile-time..
+ */
+static inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
+{
+int d0, d1;
+__asm__ __volatile__(
+       "rep ; stosl\n\t"
+       "testb $2,%b3\n\t"
+       "je 1f\n\t"
+       "stosw\n"
+       "1:\ttestb $1,%b3\n\t"
+       "je 2f\n\t"
+       "stosb\n"
+       "2:"
+       : "=&c" (d0), "=&D" (d1)
+       :"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
+       :"memory");
+return (s);    
+}
+
+/* Added by Gertjan van Wingerde to make minix and sysv module work */
+#define __HAVE_ARCH_STRNLEN
+static inline size_t strnlen(const char * s, size_t count)
+{
+int d0;
+register int __res;
+__asm__ __volatile__(
+       "movl %2,%0\n\t"
+       "jmp 2f\n"
+       "1:\tcmpb $0,(%0)\n\t"
+       "je 3f\n\t"
+       "incl %0\n"
+       "2:\tdecl %1\n\t"
+       "cmpl $-1,%1\n\t"
+       "jne 1b\n"
+       "3:\tsubl %2,%0"
+       :"=a" (__res), "=&d" (d0)
+       :"c" (s),"1" (count));
+return __res;
+}
+/* end of additional stuff */
+
+//#define __HAVE_ARCH_STRSTR
+
+//extern char *strstr(const char *cs, const char *ct);
+
+/*
+ * This looks horribly ugly, but the compiler can optimize it totally,
+ * as we by now know that both pattern and count is constant..
+ */
+static inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
+{
+       switch (count) {
+               case 0:
+                       return s;
+               case 1:
+                       *(unsigned char *)s = pattern;
+                       return s;
+               case 2:
+                       *(unsigned short *)s = pattern;
+                       return s;
+               case 3:
+                       *(unsigned short *)s = pattern;
+                       *(2+(unsigned char *)s) = pattern;
+                       return s;
+               case 4:
+                       *(unsigned long *)s = pattern;
+                       return s;
+       }
+#define COMMON(x) \
+__asm__  __volatile__( \
+       "rep ; stosl" \
+       x \
+       : "=&c" (d0), "=&D" (d1) \
+       : "a" (pattern),"0" (count/4),"1" ((long) s) \
+       : "memory")
+{
+       int d0, d1;
+       switch (count % 4) {
+               case 0: COMMON(""); return s;
+               case 1: COMMON("\n\tstosb"); return s;
+               case 2: COMMON("\n\tstosw"); return s;
+               default: COMMON("\n\tstosw\n\tstosb"); return s;
+       }
+}
+  
+#undef COMMON
+}
+
+#define __constant_c_x_memset(s, c, count) \
+(__builtin_constant_p(count) ? \
+ __constant_c_and_count_memset((s),(c),(count)) : \
+ __constant_c_memset((s),(c),(count)))
+
+#define __memset(s, c, count) \
+(__builtin_constant_p(count) ? \
+ __constant_count_memset((s),(c),(count)) : \
+ __memset_generic((s),(c),(count)))
+
+#define __HAVE_ARCH_MEMSET
+#define memset(s, c, count) \
+(__builtin_constant_p(c) ? \
+ __constant_c_x_memset((s),(0x01010101UL*(unsigned char)(c)),(count)) : \
+ __memset((s),(c),(count)))
+
+/*
+ * find the first occurrence of byte 'c', or 1 past the area if none
+ */
+#define __HAVE_ARCH_MEMSCAN
+static inline void * memscan(void * addr, int c, size_t size)
+{
+       if (!size)
+               return addr;
+       __asm__("repnz; scasb\n\t"
+               "jnz 1f\n\t"
+               "dec %%edi\n"
+               "1:"
+               : "=D" (addr), "=c" (size)
+               : "0" (addr), "1" (size), "a" (c));
+       return addr;
+}
+
+#endif
diff --git a/xen/include/asm-x86/x86_64/string.h b/xen/include/asm-x86/x86_64/string.h
new file mode 100644 (file)
index 0000000..27876b9
--- /dev/null
@@ -0,0 +1,69 @@
+#ifndef _X86_64_STRING_H_
+#define _X86_64_STRING_H_
+
+#ifdef __KERNEL__
+
+#define struct_cpy(x,y) (*(x)=*(y))
+
+/* Written 2002 by Andi Kleen */ 
+
+/* Only used for special circumstances. Stolen from i386/string.h */ 
+static inline void * __inline_memcpy(void * to, const void * from, size_t n)
+{
+unsigned long d0, d1, d2;
+__asm__ __volatile__(
+       "rep ; movsl\n\t"
+       "testb $2,%b4\n\t"
+       "je 1f\n\t"
+       "movsw\n"
+       "1:\ttestb $1,%b4\n\t"
+       "je 2f\n\t"
+       "movsb\n"
+       "2:"
+       : "=&c" (d0), "=&D" (d1), "=&S" (d2)
+       :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
+       : "memory");
+return (to);
+}
+
+/* Even with __builtin_ the compiler may decide to use the out of line
+   function. */
+
+#define __HAVE_ARCH_MEMCPY 1
+extern void *__memcpy(void *to, const void *from, size_t len); 
+#define memcpy(dst,src,len) \
+       ({ size_t __len = (len);                                \
+          void *__ret;                                         \
+          if (__builtin_constant_p(len) && __len >= 64)        \
+                __ret = __memcpy((dst),(src),__len);           \
+          else                                                 \
+                __ret = __builtin_memcpy((dst),(src),__len);   \
+          __ret; }) 
+
+
+#define __HAVE_ARCH_MEMSET
+#define memset __builtin_memset
+
+#define __HAVE_ARCH_MEMMOVE
+void * memmove(void * dest,const void *src,size_t count);
+
+/* Use C out of line version for memcmp */ 
+#define memcmp __builtin_memcmp
+int memcmp(const void * cs,const void * ct,size_t count);
+
+/* out of line string functions use always C versions */ 
+#define strlen __builtin_strlen
+size_t strlen(const char * s);
+
+#define strcpy __builtin_strcpy
+char * strcpy(char * dest,const char *src);
+
+#define strcat __builtin_strcat
+char * strcat(char * dest, const char * src);
+
+#define strcmp __builtin_strcmp
+int strcmp(const char * cs,const char * ct);
+
+#endif /* __KERNEL__ */
+
+#endif
index 26721e8240f26959f74ebf8ee2b9b518492bea4b..4688037deb453242630a1c1d87f1f163d29a6026 100644 (file)
@@ -86,7 +86,7 @@ struct pfn_info
 #define PageSetSlab(page)      ((void)0)
 #define PageClearSlab(page)    ((void)0)
 
-#define IS_XEN_HEAP_FRAME(_pfn) (page_to_phys(_pfn) < MAX_XENHEAP_ADDRESS)
+#define IS_XEN_HEAP_FRAME(_pfn) (page_to_phys(_pfn) < xenheap_phys_end)
 
 #define SHARE_PFN_WITH_DOMAIN(_pfn, _dom)                                   \
     do {                                                                    \
@@ -104,7 +104,7 @@ extern struct list_head free_list;
 extern spinlock_t free_list_lock;
 extern unsigned int free_pfns;
 extern unsigned long max_page;
-void init_frametable(unsigned long nr_pages);
+void init_frametable(void *frametable_vstart, unsigned long nr_pages);
 void add_to_domain_alloc_list(unsigned long ps, unsigned long pe);
 
 struct pfn_info *alloc_domain_page(struct domain *p);